import json

from flask import Blueprint
conversation_bp = Blueprint('conversation', __name__)
from datetime import datetime
from Test import db
from flask import Flask, request, jsonify
from config.config import Config
import openpyxl
from itertools import groupby
from operator import attrgetter
from utils.expand import *

class Conversation(db.Model,dict):
    __tablename__ = 'chat_info'
    ##主键id
    id = db.Column(db.Integer, primary_key=True)
    ##会话id
    chat_id = db.Column(db.String(80), unique=True, nullable=False)
    ##会话名称
    chat_name = db.Column(db.String(120), unique=False, nullable=False)
    ##会话持有者
    owner = db.Column(db.String(80), unique=False, nullable=False)
    ##对话详细内容
    content_detail = db.Column(db.Text, unique=False, nullable=True)
    ##关联上下文所需的内容
    conversation_content = db.Column(db.Text, unique=False, nullable=True)
    ##对话时间为DateTime类型
    create_time = db.Column(db.DateTime, nullable=True, default=datetime.now)
    ##消息类型
    content_type = db.Column(db.String(80), nullable=True, default='text')
    ##数据来源
    origin = db.Column(db.String(80), unique=False, nullable=True)


    ##对话类型  human人类，ai为人类
    type = db.Column(db.String(80), nullable=True)
    def as_dict(self):
        return {
            'id': self.id,
            'chat_id': self.chat_id,
            'chat_name': self.chat_name,
            'owner': self.owner,
            'content_detail': self.content_detail,
            'conversation_content': self.conversation_content,
            'create_time': self.create_time.strftime('%Y-%m-%d %H:%M:%S') if self.create_time else None,
            'type': self.type,
            'content_type': self.content_type,
            'origin': self.origin
        }


##新增会话接口
@conversation_bp.route('/add-conversation', methods=['POST'])
def add_conversation() -> str:
    data = request.json
    ##获取登录用户
    owner = data['owner']
    ##获取新建的会话id
    chat_id = data['chat_id']
    json_result = {}
    try:
        ##将新建的会话id存入进数据库
        new_conversation = Conversation(owner=owner, chat_id=chat_id,chat_name = 'New Conversation')
        db.session.add(new_conversation)
        db.session.commit()
        json_result['status'] = 200
        json_result['message'] = ''
        json_result['data'] = chat_id
    except Exception as e:
        print(e)
        json_result['status'] = 500
        json_result['message'] = e.__str__()
        json_result['data'] = chat_id
    return jsonify(json_result)


@conversation_bp.route('/get-conversation-content', methods=['POST'])
def get_conversation_content() -> str:
    data = request.json
    ##获取登录用户
    owner = data.get('owner')
    ##获取新建的会话id
    chat_id = data.get('chat_id')
    json_result = {}
    try:
        ##根据持有用户、会话id查询历史会话记录
        chat_info = (Conversation
                     .query
                     .filter(Conversation.owner == owner,Conversation.chat_id == chat_id,Conversation.content_detail is not None)
                     .order_by(Conversation.create_time.asc())
                     .all())
        data = []
        if len(chat_info) != 0 :
            data = [Conversation.as_dict(tmp) for tmp in chat_info]
        json_result['status'] = 200
        json_result['message'] = ''
    except Exception as e:
        print(e)
        json_result['status'] = 500
        json_result['message'] = e.__str__()
    json_result['data'] = data
    return jsonify(json_result)


@conversation_bp.route('/delete-conversation', methods=['POST'])
def delete_conversation() -> str:
    data = request.json
    ##获取登录用户
    owner = data['owner']
    ##获取新建的会话id
    chat_id = data['chat_id']
    json_result = {}
    try:
        ##根据持有用户、会话id查询历史会话记录
        chat_info_delete = (Conversation
                     .query
                     .filter(Conversation.owner == owner,Conversation.chat_id == chat_id)
                     .all())
        if len(chat_info_delete) != 0 :
            for tmp in chat_info_delete:
                db.session.delete(tmp)
        db.session.commit()
        json_result['status'] = 200
        json_result['message'] = ''
    except Exception as e:
        print(e)
        json_result['status'] = 500
        json_result['message'] = e.__str__()
    json_result['data'] = chat_id
    return jsonify(json_result)

@conversation_bp.route('/edit-conversation', methods=['POST'])
def edit_conversation() -> str:
    data = request.json
    ##获取登录用户
    owner = data['owner']
    ##获取传递的会话id
    chat_id = data['chat_id']
    ##获取传递的会话名称
    chat_name = data['chat_name']

    json_result = {}
    try:
        ##根据持有用户、会话id查询历史会话记录
        chat_info_edit = (Conversation
                     .query
                     .filter(Conversation.owner == owner,Conversation.chat_id == chat_id)
                     .all())
        if len(chat_info_edit) != 0 :
            for tmp in chat_info_edit:
                tmp.chat_name = chat_name
        db.session.commit()
        json_result['status'] = 200
        json_result['message'] = ''
    except Exception as e:
        print(e)
        json_result['status'] = 500
        json_result['message'] = e.__str__()
    json_result['data'] = chat_id
    return jsonify(json_result)



##根据每个会话的最老的一条数据，然后按照时间进行排序
@conversation_bp.route('/get-conversation-list', methods=['POST'])
def get_conversation_list() -> str:
    data = request.json
    ##获取登录用户
    owner = data['owner']
    json_result = {}
    try:
        ##根据持有用户、会话id查询历史会话记录
        chat_info = (Conversation
                     .query
                     .filter(Conversation.owner == owner and Conversation.chat_id is not None)
                     .all())
        json_result['status'] = 200
        json_result['message'] = ''
        if len(chat_info) != 0 :
            # 首先按照chat_id进行分组
            chat_info.sort(key=lambda x: x.chat_id)
            groups = {}
            for key, group in groupby(chat_info, key=lambda x: x.chat_id):
                groups[key] = list(group)
            # 对每个分组中的对象按照时间进行排序，并取出每组会话id中的最初元素
            result = {}
            for key, group in groups.items():
                sorted_group = sorted(group, key=attrgetter('create_time'))
                result[key] = sorted_group[0]
            conversations  = result.values()
            sorted_conversation = sorted(conversations, key=lambda x: x.create_time, reverse=True)

            # 对象集合按照 id 属性排序（必须先排序）
            # sorted_objects = sorted(chat_info, key=attrgetter('chat_id'))
            # unique_objects = deduplicate_by_property(sorted_objects, 'chat_id')
            data = [Conversation.as_dict(tmp) for tmp in sorted_conversation]
        json_result['data'] = data
    except Exception as e:
        print(e)
        logging.error('get-conversation-list接口出现异常')
        json_result['status'] = 500
        json_result['message'] = e.__str__()
    return jsonify(json_result)

@timecost
def get_lastest_history_messsage(chat_id, owner) ->[]:
    chat_info = (Conversation
                 .query
                 .filter(Conversation.owner == owner, Conversation.chat_id == chat_id,Conversation.type != '')
                 .order_by(Conversation.create_time.asc())
                 .all())
    max_num_conversation = Config.max_num_conversation
    max_token  = Config.max_token
    history_message = []
    while max_num_conversation > 0 and len(chat_info) != 0:
        # 取倒数 最大对话条数元素
        selected_messages = chat_info[-max_num_conversation:]
        # 计算token消耗
        consumer_token = num_tokens_from_messages(selected_messages)
        # 判断是否满足条件
        if consumer_token < max_token:
            # 如果满足条件跳出循环
            break
        # 如果不满足条件，减少倒数元素个数，继续下一轮循环
        max_num_conversation -= 1
    if len(chat_info) != 0:
        chat_history = chat_info[-max_num_conversation:]
        for tmp in chat_history:
            type = tmp.type
            conversation_content = tmp.conversation_content
            tmp_dict= {"role": type,"content":conversation_content}
            history_message.append(tmp_dict)
    return  history_message


##计算每条消息消耗的token
def num_tokens_from_messages(conversation_messages: list, model="gpt-3.5-turbo-0613") -> int:
    if len(conversation_messages) == 0:
        return True
    # 初始化 GPT-3 编码器
    encoding = tiktoken.get_encoding("cl100k_base")
    # 计算每个字符串的 token 数量
    token_counts_list = [len(encoding.encode(tmp.conversation_content)) for tmp in conversation_messages]
    total_consume = sum(token_counts_list)
    return  total_consume


@conversation_bp.route('/get-table-file', methods=['POST'])
def get_table_file_bychatid() -> str:
    save_path_prefix = Config.save_file_path_prefix
    data = request.json
    ##获取登录用户
    id = data['id']
    json_result = {}
    ##根据持有用户、会话id查询历史会话记录
    chat_data = (Conversation
                 .query
                 .filter(Conversation.id == id)
                 .all())
    if len(chat_data) == 0:
        json_result['status'] = 500
        json_result['message'] = '该条数据查无，已被删除，请刷新页面后重试'
        json_result['data'] = ''
        return jsonify(json_result)
    try:
        if len(chat_data) != 0 :
            chat_info = chat_data[0]
            table_data_str = chat_info.conversation_content
            table_data = json.loads(table_data_str)
            if len(table_data) != 0:
                result_filepath = save_path_prefix + str(id) + '.xlsx'

                wb = openpyxl.Workbook()
                sheet = wb.active

                # 写入表头，使用第一个 JSON 数据的键作为列名
                headers = list(table_data[0].keys())
                sheet.append(headers)

                # 逐行写入数据
                for row_data in table_data:
                    row_values = list(row_data.values())
                    sheet.append(row_values)
                # 保存工作簿
                wb.save(result_filepath)
                json_result['status'] = 200
                json_result['message'] = '生成excel成功,返回文件结果路径'
                json_result['data'] = result_filepath

    except Exception as e:
        logging.error('get-table-file接口出现异常，异常原因为'+str(e))
        json_result['status'] = 500
        json_result['message'] = '生成excel逻辑出现异常'
        json_result['data'] = ''

    return jsonify(json_result)

